在前幾天,我們學會了變數與條件判斷 (if/else、switch)。
今天要來介紹程式裡另一個重要的工具:迴圈 (Loop)。
迴圈的用途是「重複做某件事」,特別適合用在處理一整份股票清單時。
假設我們有一個股票價格清單:
double[] prices = { 80, 120, 95, 150 };
如果要檢查每一檔股票是否大於 100,你會怎麼做?
用 if/else,一支一支股票寫下來:
if (prices[0] > 100) Console.WriteLine("股票 1 進入觀察名單");
if (prices[1] > 100) Console.WriteLine("股票 2 進入觀察名單");
if (prices[2] > 100) Console.WriteLine("股票 3 進入觀察名單");
if (prices[3] > 100) Console.WriteLine("股票 4 進入觀察名單");
👉 這樣太笨重了,萬一股票有上百檔,程式就會長到天荒地老。
這時候就需要 迴圈!
for 適合在「知道要跑幾次」的時候使用。
double[] prices = { 80, 120, 95, 150 };
for (int i = 0; i < prices.Length; i++)
{
    if (prices[i] > 100)
    {
        Console.WriteLine($"股票 {i + 1} 價格 {prices[i]} → 進入觀察名單");
    }
}
執行結果:
股票 2 價格 120 → 進入觀察名單
股票 4 價格 150 → 進入觀察名單
如果你只是想「逐一讀取清單裡的每個值」,foreach 會更簡潔。
double[] prices = { 80, 120, 95, 150 };
int index = 1;
foreach (var price in prices)
{
    if (price > 100)
    {
        Console.WriteLine($"股票 {index} 價格 {price} → 進入觀察名單");
    }
    index++;
}
👉 適合處理「集合 (List/Array)」的情境。
很多時候,我們需要「逐一檢查清單內容,若條件成立就移除」。
直覺寫法如下 —— 但這會出錯:
var prices = new List<double> { 80, 120, 95, 150 };
foreach (var p in prices)
{
    if (p <= 100)
        prices.Remove(p); // ❌ System.InvalidOperationException
}
因為 foreach 透過 列舉器 (Enumerator) 來讀取清單。
當你在迴圈裡修改集合(Remove 或 Add),版本不一致,列舉器就會丟 InvalidOperationException,避免資料錯亂。
var prices = new List<double> { 80, 120, 95, 150 };
for (int i = prices.Count - 1; i >= 0; i--)
{
    if (prices[i] <= 100)
        prices.RemoveAt(i);
}
var prices = new List<double> { 80, 120, 95, 150 };
var toRemove = new List<double>();
foreach (var p in prices)
{
    if (p <= 100) toRemove.Add(p);
}
foreach (var p in toRemove)
    prices.Remove(p);
foreach (var p in prices.ToList())
{
    if (p <= 100) prices.Remove(p);
}
prices.RemoveAll(p => p <= 100);
為什麼 foreach 在刪除時會丟錯?這要從「物件 (Object)」來理解。
List<T> 是一個 類別 (Class),當你寫:
var prices = new List<double> { 80, 120, 95, 150 };
這個 prices 就是一個 List<double> 類別的 物件 (Object)。
物件有狀態:prices 裡的數字就是狀態。
物件有行為:Add()、Remove()、Count 都是它的功能。
foreach 用的是 列舉器 (Enumerator) 物件,會監控集合的版本。
當你在列舉中修改集合,它會檢測到版本不一致,丟出例外,保護資料一致性。
👉 這就是「物件」的特性之一:不只是資料袋,而是有規則的實體。
while 適合「不知道要跑幾次,但有條件決定是否繼續」的情境。
double[] prices = { 80, 120, 95, 150 };
int i = 0;
while (i < prices.Length)
{
    if (prices[i] > 100)
    {
        Console.WriteLine($"股票 {i + 1} 價格 {prices[i]} → 進入觀察名單");
    }
    i++;
}
要小心 while,如果忘記更新條件,會變成無窮迴圈:
int i = 0;
while (i < 5)
{
    Console.WriteLine("這行會跑不完...");
    // 忘記寫 i++,永遠卡住!
}
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
    static void Main(string[] args)
    {
        var prices = new List<double> { 80, 120, 95, 150 };
        Console.WriteLine("=== for 迴圈 ===");
        for (int i = 0; i < prices.Count; i++)
        {
            if (prices[i] > 100)
                Console.WriteLine($"股票 {i + 1} 價格 {prices[i]} → 進入觀察名單");
        }
        Console.WriteLine("=== foreach 迴圈 ===");
        int index = 1;
        foreach (var price in prices)
        {
            if (price > 100)
                Console.WriteLine($"股票 {index} 價格 {price} → 進入觀察名單");
            index++;
        }
        Console.WriteLine("=== while 迴圈 ===");
        int j = 0;
        while (j < prices.Count)
        {
            if (prices[j] > 100)
                Console.WriteLine($"股票 {j + 1} 價格 {prices[j]} → 進入觀察名單");
            j++;
        }
        Console.WriteLine("=== 移除小於等於 100 的股票 ===");
        prices.RemoveAll(p => p <= 100); // 精簡做法
        foreach (var price in prices)
        {
            Console.WriteLine($"剩餘股票價格:{price}");
        }
    }
}
執行結果:
=== for 迴圈 ===
股票 2 價格 120 → 進入觀察名單
股票 4 價格 150 → 進入觀察名單
=== foreach 迴圈 ===
股票 2 價格 120 → 進入觀察名單
股票 4 價格 150 → 進入觀察名單
=== while 迴圈 ===
股票 2 價格 120 → 進入觀察名單
股票 4 價格 150 → 進入觀察名單
=== 移除小於等於 100 的股票 ===
剩餘股票價格:120
剩餘股票價格:150
今天我們學會了:
List<T> 是物件,有狀態與行為,foreach 的列舉器會檢查集合版本---
明天,我們要介紹 方法 (Method) —— 怎麼把「計算股票邏輯」抽出來,避免同一段程式碼重複出現。